package com.slyak.spring.jpa;

import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * .
 * <p/>
 *
 * @author <a href="mailto:stormning@163.com">stormning</a>
 * @version V1.0, 2015/8/22.
 */
public abstract class EntityAssemblerMany<T, K, V> implements EntityAssembler<T> {

	@Override
	public void assemble(T bean) {
		if (bean == null) {
			return;
		}
		setValue(bean, safeGetValue(getKeys(bean)));
	}

	@Override
	public void massemble(Iterable<T> beans) {
		if (beans == null || !beans.iterator().hasNext()) {
			return;
		}
		Set<K> keys = new HashSet<K>();
		for (T bean : beans) {
			if (bean != null) {
				List<K> ks = getKeys(bean);
				if (!CollectionUtils.isEmpty(ks)) {
					for (K k : ks) {
						keys.add(k);
					}
				}
			}
		}

		if (!CollectionUtils.isEmpty(keys)) {
			Map<K, V> valueMap = mgetValue(keys);

			for (T bean : beans) {
				if (bean != null) {
					List<K> ks = getKeys(bean);
					if (!CollectionUtils.isEmpty(ks)) {
						List<V> values = new ArrayList<V>();
						for (K k : ks) {
							values.add(valueMap.get(k));
						}
						setValue(bean, values);
					}
				}
			}
		}
	}

	protected abstract void setValue(T bean, List<V> value);

	private List<V> safeGetValue(List<K> keys) {
		if (CollectionUtils.isEmpty(keys)) {
			return Collections.emptyList();
		}
		return getValue(keys);
	}

	protected abstract List<V> getValue(List<K> keys);

	protected abstract List<K> getKeys(T bean);

	protected abstract Map<K, V> mgetValue(Collection<K> keys);
}
